package com.hqyj.fj.javaSpringBoot.modules.account.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hqyj.fj.javaSpringBoot.modules.account.dao.ResourceDao;
import com.hqyj.fj.javaSpringBoot.modules.account.dao.ResourceDaoR;
import com.hqyj.fj.javaSpringBoot.modules.account.dao.RoleResourceDao;
import com.hqyj.fj.javaSpringBoot.modules.account.entity.Resource;
import com.hqyj.fj.javaSpringBoot.modules.account.entity.Role;
import com.hqyj.fj.javaSpringBoot.modules.account.entity.RoleResource;
import com.hqyj.fj.javaSpringBoot.modules.account.entity.User;
import com.hqyj.fj.javaSpringBoot.modules.account.service.ResourceService;
import com.hqyj.fj.javaSpringBoot.modules.common.entity.Result;
import com.hqyj.fj.javaSpringBoot.modules.common.entity.SearchBean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ResourceDao resourceDao;

    @Autowired
    private ResourceDaoR resourceDaoR;

    @PersistenceContext
    private EntityManager entityManager;

    @Autowired
    private RoleResourceDao roleResourceDao;
    @Override
    public Result<Resource> editResource(Resource resource) {
         resourceDao.saveAndFlush(resource);
        return new Result<Resource>(Result.ResultCode.SUCCESS.code,
                "Insert success.", resource);
    }

    @Override
    @Transactional
    public Result<Resource> insertResource(Resource resource) {
        resource.setCreateDate(LocalDateTime.now());
        resourceDao.saveAndFlush(resource);
        if (resource.getRoles() != null) {
            resource.getRoles().stream()
                    .forEach(item -> {
                        roleResourceDao.insertRoleResource(new RoleResource(item.getId(), resource.getId()));
                    });
        }
        return new Result<Resource>(Result.ResultCode.SUCCESS.code, "Insert success", resource);
    }

    @Override
    @Transactional
    public Result<Resource> updateResource(Resource resource) {
        resourceDao.saveAndFlush(resource);
        roleResourceDao.deleteRoleResourceByResourceId(resource.getId());
        if (resource.getRoles() != null) {
            resource.getRoles().stream()
                    .forEach(item -> {roleResourceDao.insertRoleResource(new RoleResource(item.getId(), resource.getId()));});
        }
        return new Result<Resource>(Result.ResultCode.SUCCESS.code, "Update success", resource);
    }

    @Override
    public Result<Object> deleteResourceById(int id){
        resourceDao.deleteById(id);
        return new Result<Object>(Result.ResultCode.SUCCESS.code,
                "Delete success.");
    }

    @Override
    public Resource getResourceById(int id) {
     return    resourceDaoR.getResourceById(id);
//        return resourceDao.getById(id);
    }

    @Override
    public List<Resource> getResourceByPermit(String permit) {
        return resourceDao.findResourcesByPermit(permit);
    }

    @Override
    public Page<Resource> getResourceBySearchBean(SearchBean searchBean) {
        Sort.Direction direction = StringUtils.isBlank(searchBean.getDirection()) ||
                searchBean.getDirection().toLowerCase().equals("asc") ?
                Sort.Direction.ASC : Sort.Direction.DESC;
        Sort sort = Sort.by(direction, searchBean.getOrderBy());
        Pageable Pageable = PageRequest.of(
                searchBean.getCurrentPage() - 1,
                searchBean.getPageSize(),
                sort);

            Resource resource = new Resource();
        resource.setPermit(searchBean.getKeyword());
        ExampleMatcher matcher = ExampleMatcher
                .matchingAny()
                .withMatcher("permit", match -> match.contains());

        Example example = Example.of(resource, matcher);

        return resourceDao.findAll(example, Pageable);
    }

    @Override
    @Transactional
    public Result<Object> insertResources(List<Resource> resourceList) {
        resourceList.stream().forEach(item ->{
            entityManager.persist(item);
        });
        entityManager.flush();
        entityManager.clear();
        return  new Result<Object>(Result.ResultCode.SUCCESS.code,"insert success");
    }

    @Override
    public List<Resource> getResourcesByRoleId(int roleId) {
        return resourceDaoR.getResourcesByRoleId(roleId);
    }

}
